//============================================================================
// Name        : ms005.cpp
// Author      : Tadas
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include "comp.h"

#define EPS 1e-6
#define JMAX 100

using namespace std;

komp polin(komp x, komp c[], int n) {

	komp p(c[n]);

	for (int j = n - 1; j >= 0; j--) {
		p = p * x + c[j];
	}

	return p;
}

void solver(komp c[], komp ans[], int n) {

	//cout << n << endl;

	komp q, A, B, C, x1, x2, x3, x4, D, temp;
	komp ktemp(0.5, 0);
	int dd = n;
	for (int k = 0; k < dd; k++) {

		x1 = 1.0;
		x2 = 2.0;
		x3 = 3.0;
		x4 = 0.0;
		for (int j = 0; j < JMAX; j++) {
			komp bot =  (x2 - x1);
			q = (x3 - x2) / bot;
			A = q * polin(x3, c, n) - q * (q + 1) * polin(x2, c, n) + q * q * polin(
					x1, c, n);
			B = (2 * q + 1) * polin(x3, c, n) - (q + 1) * (q + 1) * polin(x2, c, n)
					+ q * q * polin(x1, c, n);
			C = (q + 1) * polin(x3, c, n);

			//				cout << A << endl;
			//				x4 = x3 - (x3 - x2) * (2 * C);
			//				ktemp = (B * B - 4 * A * C).sqr();
			//				if( B.mod() > 0){
			//					 ktemp = B + ktemp;
			//				}
			//				else{
			//
			//					ktemp = (B - ktemp);
			//				}
			//
			//				 x4 = x4/ktemp;

			
			D = B * B - 4 * A * C;
			temp = D.sqr();
			if ((B + temp).mod() > (B - temp).mod()) {
				x4 = x3 - (x3 - x2) * (2 * C) / (B + temp);
			} else {
				x4 = x3 - (x3 - x2) * (2 * C) / (B - temp);
			}

			//				cout << "x4: " << x4 << endl;
			if ((x4 - x3).abs() < EPS * (x4.abs())) {
				komp rem(c[n]);
				c[n] = 0.0;
				for (j = n - 1; j >= 0; j--) {
					komp swap = c[j];
					c[j] = rem;
					rem = swap + rem * x4;
				}
				ans[k].set(x4);
				n--;
				break;
			}

			x1 = x2;
			x2 = x3;
			x3 = x4;
			x4 = 0.0;
		}

	}

}

int main() {
	komp c[5], b[5];
	//	komp c[] = { new komp(-2.0.0), new komp(-1.0, 0.0), new komp(-1.0, 0.0), new komp(-1.0, 0.0), new komp(-1.0, 0.0) };
	//	komp * tmp;
	//	tmp = new komp(-2.0 , 0.0);
	c[0].set(-2.0, 0.0);
	c[1].set(-1.0, 0.0);
	c[2].set(-1.0, 0.0);
	c[3].set(-1.0, 0.0);
	c[4].set(1.0, 0.0);
	
	b[0].set(-1.98, 0.0);
	b[1].set(4.99, 0.0);
	b[2].set(-3.01, 0.0);
	b[3].set(-1.0, 0.0);
	b[4].set(1.0, 0.0);
	
	komp ans[5];
	komp ans2[5];

	int n = sizeof(c) / sizeof(komp);
	
	solver(c, ans, n);
	solver(b, ans2, n);

	for (int i = 0; i < n; i++) {
		cout << "F1: " << ans[i] << endl;
		cout << "F2: " << ans2[i] << endl;
	}
	komp temp(2.49999,0.0);
	cout << polin(temp, b, n) << endl;

	return EXIT_SUCCESS;
}
